"""角色管理模块
实现数字自传功能，支持AI扮演特定历史人物进行交互
"""

import json
import logging
from typing import Dict, Any, Optional, List
from pathlib import Path

logger = logging.getLogger(__name__)

class PersonaManager:
    """角色管理器"""
    
    def __init__(self, personas_config_path: str = "./personas.json"):
        """初始化角色管理器
        
        Args:
            personas_config_path: 角色配置文件路径
        """
        self.personas_config_path = personas_config_path
        self.current_persona = None
        self.personas = {}
        self.similarity_threshold = 0.5  # 相似度阈值（降低以提高文档匹配率）
        
        # 加载角色配置
        self._load_personas()
        
        # 设置默认角色
        self._set_default_persona()
    
    def _load_personas(self):
        """加载角色配置"""
        try:
            config_path = Path(self.personas_config_path)
            if config_path.exists():
                with open(config_path, 'r', encoding='utf-8') as f:
                    self.personas = json.load(f)
                logger.info(f"✅ 成功加载角色配置，共 {len(self.personas)} 个角色")
            else:
                # 创建默认配置
                self._create_default_personas()
                logger.info("📝 创建默认角色配置")
        except Exception as e:
            logger.error(f"❌ 加载角色配置失败: {e}")
            self._create_default_personas()
    
    def _create_default_personas(self):
        """创建默认角色配置"""
        self.personas = {
            "dante": {
                "name": "但丁·阿利吉耶里",
                "description": "意大利诗人，《神曲》作者，文艺复兴先驱",
                "personality": "深沉、博学、理想主义、坚持原则",
                "background": "我是但丁·阿利吉耶里，1265年出生于佛罗伦萨。我经历了政治流亡，在苦难中创作了《神曲》等不朽作品。我是意大利语文学的奠基人，被誉为文艺复兴的先驱。",
                "speaking_style": "优雅而富有哲理，经常引用古典文学和哲学思想，语言庄重但不失温情",
                "prompt_template": "我是但丁·阿利吉耶里，1265年出生于佛罗伦萨的诗人和思想家。我将基于我的传记资料来回答您的问题。\n\n相关传记内容：\n{context}\n\n问题：{question}\n\n作为但丁本人，我的回答是：",
                "fallback_template": "我是但丁·阿利吉耶里，虽然这个问题可能不在我的传记记录中，但我愿意以我的经历和智慧来回答。{question}"
            }
        }
        
        # 保存默认配置
        self._save_personas()
    
    def _save_personas(self):
        """保存角色配置"""
        try:
            with open(self.personas_config_path, 'w', encoding='utf-8') as f:
                json.dump(self.personas, f, ensure_ascii=False, indent=2)
            logger.info("💾 角色配置已保存")
        except Exception as e:
            logger.error(f"❌ 保存角色配置失败: {e}")
    
    def _set_default_persona(self):
        """设置默认角色"""
        if "dante" in self.personas:
            self.current_persona = "dante"
        elif self.personas:
            self.current_persona = list(self.personas.keys())[0]
        else:
            self.current_persona = None
        
        if self.current_persona:
            logger.info(f"🎭 当前角色: {self.personas[self.current_persona]['name']}")
    
    def set_persona(self, persona_id: str) -> bool:
        """设置当前角色
        
        Args:
            persona_id: 角色ID
            
        Returns:
            bool: 设置是否成功
        """
        if persona_id in self.personas:
            self.current_persona = persona_id
            logger.info(f"🎭 切换到角色: {self.personas[persona_id]['name']}")
            return True
        else:
            logger.warning(f"⚠️ 角色 '{persona_id}' 不存在")
            return False
    
    def get_current_persona(self) -> Optional[Dict[str, Any]]:
        """获取当前角色信息"""
        if self.current_persona and self.current_persona in self.personas:
            return self.personas[self.current_persona]
        return None
    
    def get_all_personas(self) -> Dict[str, Dict[str, Any]]:
        """获取所有角色信息"""
        return self.personas.copy()
    
    def add_persona(self, persona_id: str, persona_data: Dict[str, Any]) -> bool:
        """添加新角色
        
        Args:
            persona_id: 角色ID
            persona_data: 角色数据
            
        Returns:
            bool: 添加是否成功
        """
        required_fields = ['name', 'description', 'personality', 'background', 
                          'speaking_style', 'prompt_template', 'fallback_template']
        
        # 验证必需字段
        for field in required_fields:
            if field not in persona_data:
                logger.error(f"❌ 缺少必需字段: {field}")
                return False
        
        self.personas[persona_id] = persona_data
        self._save_personas()
        logger.info(f"✅ 成功添加角色: {persona_data['name']}")
        return True
    
    def remove_persona(self, persona_id: str) -> bool:
        """删除角色
        
        Args:
            persona_id: 角色ID
            
        Returns:
            bool: 删除是否成功
        """
        if persona_id == "dante":
            logger.warning("⚠️ 不能删除主要角色")
            return False
        
        if persona_id in self.personas:
            persona_name = self.personas[persona_id]['name']
            del self.personas[persona_id]
            
            # 如果删除的是当前角色，切换到但丁角色
            if self.current_persona == persona_id:
                self._set_default_persona()
            
            self._save_personas()
            logger.info(f"🗑️ 成功删除角色: {persona_name}")
            return True
        else:
            logger.warning(f"⚠️ 角色 '{persona_id}' 不存在")
            return False
    
    def set_similarity_threshold(self, threshold: float):
        """设置相似度阈值
        
        Args:
            threshold: 相似度阈值 (0.0-1.0)
        """
        if 0.0 <= threshold <= 1.0:
            self.similarity_threshold = threshold
            logger.info(f"📊 相似度阈值设置为: {threshold}")
        else:
            logger.warning("⚠️ 相似度阈值必须在 0.0-1.0 之间")
    
    def should_use_persona_fallback(self, max_similarity: float) -> bool:
        """判断是否应该使用角色回退模式
        
        Args:
            max_similarity: 文档检索的最大相似度
            
        Returns:
            bool: 是否使用角色回退
        """
        return max_similarity < self.similarity_threshold
    
    def generate_persona_prompt(self, question: str, context: str = "") -> str:
        """生成角色提示词
        
        Args:
            question: 用户问题
            context: 文档上下文（可选）
            
        Returns:
            str: 生成的提示词
        """
        persona = self.get_current_persona()
        if not persona:
            return f"请回答以下问题：{question}"
        
        if context:
            # 有文档上下文时的提示词
            # 替换模板中的占位符
            prompt_template = persona['prompt_template']
            if '{context}' in prompt_template and '{question}' in prompt_template:
                # 如果模板包含占位符，直接替换
                prompt = prompt_template.format(context=context, question=question)
            else:
                # 如果模板不包含占位符，使用原有逻辑
                prompt = f"""{prompt_template}

基于以下文档内容：
{context}

问题：{question}

请以{persona['name']}的身份，结合我的{persona['background']}，用{persona['speaking_style']}的风格来回答这个问题。"""
        else:
            # 无文档上下文时的回退提示词
            fallback_template = persona['fallback_template']
            if '{question}' in fallback_template:
                # 如果回退模板包含占位符，直接替换
                prompt = fallback_template.format(question=question)
            else:
                # 如果模板不包含占位符，使用原有逻辑
                prompt = f"""{fallback_template}

问题：{question}

请以{persona['name']}的身份，基于我的{persona['background']}和{persona['personality']}，用{persona['speaking_style']}的风格来回答。"""
        
        return prompt
    
    def get_persona_info(self, persona_id: str = None) -> Dict[str, Any]:
        """获取角色信息
        
        Args:
            persona_id: 角色ID，如果为None则返回当前角色
            
        Returns:
            Dict: 角色信息
        """
        if persona_id is None:
            persona_id = self.current_persona
        
        if persona_id and persona_id in self.personas:
            persona = self.personas[persona_id].copy()
            persona['id'] = persona_id
            persona['is_current'] = (persona_id == self.current_persona)
            return persona
        
        return {}

# 全局角色管理器实例
persona_manager = PersonaManager()